<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IPv4地址与二进制转换工具</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        dark: '#1E293B',
                        light: '#F8FAFC'
                    },
                    fontFamily: {
                        inter: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .bit-box {
                @apply w-10 h-10 flex items-center justify-center border rounded-md transition-all duration-300 text-lg font-medium;
            }
            .bit-box-active {
                @apply bg-primary/20 border-primary;
            }
            .octet-container {
                @apply flex flex-col gap-1 mb-4;
            }
            .bit-weight {
                @apply text-xs text-gray-500;
            }
            .transition-smooth {
                @apply transition-all duration-300 ease-in-out;
            }
        }
    </style>
    <!-- 添加全局样式 -->
    <style>
        input {
            outline: none;
        }
    </style>
</head>
<body class="bg-gradient-to-br from-light to-blue-50 min-h-screen font-inter text-dark">
    <div class="container mx-auto px-4 py-8 w-[88%] max-w-none">
        <!-- 页面标题 -->
        <header class="text-center mb-10">
            <h1 class="text-[clamp(2rem,5vw,3.5rem)] font-bold text-transparent bg-clip-text bg-gradient-to-r from-primary to-secondary mb-3">
                IPv4 地址与二进制转换工具
            </h1>
            <p class="text-lg text-gray-600 max-w-2xl mx-auto">
                探索32位IPv4地址与二进制的关系，直观理解IP地址的构成原理
            </p>
        </header>

        <!-- 主要内容区域 -->
        <main class="grid md:grid-cols-12 gap-8">
            <!-- 左侧：输入和转换区域 -->
            <section class="bg-white rounded-2xl shadow-lg p-6 transform hover:shadow-xl transition-smooth md:col-span-8">
                <h2 class="text-2xl font-bold mb-6 text-dark border-b pb-3">
                    <i class="fa fa-exchange text-primary mr-2"></i>转换工具
                </h2>

                <!-- IP地址输入 -->
                <div class="mb-8">
                    <label for="ipAddress" class="block text-gray-700 font-medium mb-2">
                        IPv4 地址 (点分十进制)
                    </label>
                    <div class="flex items-center gap-2 flex-wrap">
                        <input type="text" id="ipAddress" placeholder="例如: 192.168.1.1" 
                            class="flex-1 px-4 py-3 border border-gray-300 rounded-lg transition-smooth focus:border-primary min-w-[200px]">
                        <div class="flex gap-2">
                            <button id="randomIpBtn" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-3 rounded-lg transition-smooth">
                                <i class="fa fa-random mr-1"></i> 随机IP
                            </button>
                            <button id="convertToBinaryBtn" class="bg-primary hover:bg-primary/90 text-white px-4 py-3 rounded-lg transition-smooth">
                                <i class="fa fa-arrow-right mr-1"></i> 转换
                            </button>
                        </div>
                    </div>
                    <div id="ipLoader" class="mt-2 text-sm text-gray-500 hidden">
                        <i class="fa fa-circle-o-notch fa-spin mr-1"></i>正在获取您的IP地址...
                    </div>
                    <div id="ipLocation" class="mt-2 text-sm text-gray-600 hidden">
                        <i class="fa fa-map-marker mr-1"></i><span id="locationText">中国 - 贵州 - 黔东南苗族侗族自治州 移动</span>
                    </div>
                    <p id="ipError" class="text-red-500 mt-2 hidden">请输入有效的IPv4地址</p>
                </div>

                <!-- 二进制显示 -->
                <div class="mb-8">
                    <label class="block text-gray-700 font-medium mb-2">
                        32位二进制表示
                    </label>
                    <div id="binaryDisplay" class="grid grid-cols-4 gap-6">
                        <!-- 四个八位组将由JS动态生成 -->
                    </div>
                </div>

                <!-- 二进制输入 -->
                <div class="mb-8">
                    <label for="binaryInput" class="block text-gray-700 font-medium mb-2">
                        二进制输入 (32位)
                    </label>
                    <div class="flex items-center gap-2">
                        <input type="text" id="binaryInput" placeholder="例如: 11000000.10101000.00000001.00000001" 
                            class="flex-1 px-4 py-3 border border-gray-300 rounded-lg transition-smooth focus:border-primary">
                        <button id="convertToIpBtn" class="bg-secondary hover:bg-secondary/90 text-white px-4 py-3 rounded-lg transition-smooth">
                            <i class="fa fa-arrow-right mr-1"></i> 转换
                        </button>
                    </div>
                    <p id="binaryError" class="text-red-500 mt-2 hidden">请输入有效的32位二进制地址</p>
                </div>

                <!-- IP显示 -->
                <div>
                    <label class="block text-gray-700 font-medium mb-2">
                        IPv4 地址结果
                    </label>
                    <div id="ipResult" class="px-4 py-3 bg-gray-100 rounded-lg text-lg font-mono">
                        0.0.0.0
                    </div>
                </div>
            </section>

            <!-- 右侧：信息和可视化区域 -->
            <section class="bg-white rounded-2xl shadow-lg p-6 transform hover:shadow-xl transition-smooth md:col-span-4">
                <h2 class="text-2xl font-bold mb-6 text-dark border-b pb-3">
                    <i class="fa fa-info-circle text-primary mr-2"></i>知识讲解
                </h2>

                <!-- 什么是IPv4 -->
                <div class="mb-6">
                    <h3 class="text-xl font-semibold mb-2 text-primary">什么是IPv4?</h3>
                    <p class="text-gray-700 mb-3">
                        IPv4（Internet Protocol version 4）是互联网协议的第四版，也是使用最广泛的版本。
                        每个IPv4地址由32位二进制数组成，通常表示为四个十进制数，每个数范围从0到255，用点分隔（例如：192.168.1.1）。
                    </p>
                </div>

                <!-- 二进制与IPv4关系 -->
                <div class="mb-6">
                    <h3 class="text-xl font-semibold mb-2 text-primary">二进制与IPv4的关系</h3>
                    <p class="text-gray-700 mb-3">
                        32位的IPv4地址可以分为四个8位的组（称为八位组）。每个八位组可以转换为一个0-255之间的十进制数。
                        例如，二进制数 <span class="bg-yellow-100 px-1 font-mono">11100000</span> 对应的十进制数是 <span class="bg-yellow-100 px-1 font-mono">224</span>。
                    </p>
                </div>

                <!-- 可视化解释 -->
                <div class="mb-6">
                    <h3 class="text-xl font-semibold mb-2 text-primary">直观理解</h3>
                    <div class="bg-blue-50 p-4 rounded-lg" id="visualizationExample">
                        <p class="text-center text-gray-500 italic">输入IP地址并转换为二进制以查看动态可视化</p>
                    </div>
                </div>

                <!-- 用途 -->
                <div>
                    <h3 class="text-xl font-semibold mb-2 text-primary">为什么这很重要?</h3>
                    <p class="text-gray-700">
                        理解IPv4地址与二进制的关系对于网络配置、故障排除和网络安全至关重要。
                        它是计算机网络基础课程中的重要概念，也是理解更高级网络主题的基础。
                    </p>
                </div>
            </section>
        </main>

        <!-- 互动练习区域 -->
        <section class="mt-10 bg-white rounded-2xl shadow-lg p-6 transform hover:shadow-xl transition-smooth">
            <h2 class="text-2xl font-bold mb-6 text-dark border-b pb-3">
                <i class="fa fa-pencil-square-o text-primary mr-2"></i>互动练习
            </h2>
            <p class="text-gray-700 mb-6">
                测试你的理解！尝试完成以下练习，然后使用上面的工具检查你的答案。
            </p>
            
            <div class="grid md:grid-cols-2 gap-6">
                <div class="bg-blue-50 p-4 rounded-lg">
                    <h3 class="font-semibold text-lg mb-3">练习 1</h3>
                    <p class="mb-2">将IPv4地址 <span class="font-mono">10.0.0.1</span> 转换为二进制。</p>
                    <div class="flex items-center mt-3">
                        <input type="text" id="exercise1" placeholder="输入你的答案" 
                            class="flex-1 px-3 py-2 border border-gray-300 rounded-lg transition-smooth focus:border-primary">
                        <button id="checkExercise1" class="ml-2 bg-primary hover:bg-primary/90 text-white px-3 py-2 rounded-lg transition-smooth">
                            检查
                        </button>
                    </div>
                    <p id="exercise1Result" class="mt-2 text-sm hidden"></p>
                </div>
                
                <div class="bg-blue-50 p-4 rounded-lg">
                    <h3 class="font-semibold text-lg mb-3">练习 2</h3>
                    <p class="mb-2">将二进制地址 <span class="font-mono">11100000.00010000.00000010.00000011</span> 转换为IPv4格式。</p>
                    <div class="flex items-center mt-3">
                        <input type="text" id="exercise2" placeholder="输入你的答案" 
                            class="flex-1 px-3 py-2 border border-gray-300 rounded-lg transition-smooth focus:border-secondary">
                        <button id="checkExercise2" class="ml-2 bg-primary hover:bg-primary/90 text-white px-3 py-2 rounded-lg transition-smooth">
                            检查
                        </button>
                    </div>
                    <p id="exercise2Result" class="mt-2 text-sm hidden"></p>
                </div>
            </div>
        </section>

        <!-- 页脚 -->
        <footer class="mt-12 text-center text-gray-500 text-sm">
            <p>© 2025 IPv4与二进制转换工具 | 专为初中信息科技课程设计</p>
        </footer>
    </div>

    <script>
        // 获取用户IP地址
        async function fetchUserIp() {
            const ipLoader = document.getElementById('ipLoader');
            const ipAddressInput = document.getElementById('ipAddress');
            const ipLocation = document.getElementById('ipLocation');
            const locationText = document.getElementById('locationText');
            
            try {
                // 显示加载状态
                ipLoader.classList.remove('hidden');
                ipLocation.classList.add('hidden');
                
                // 发送请求获取IP地址
                const response = await fetch('http://v4.ip.zxinc.org/info.php?type=json');
                
                if (!response.ok) {
                    throw new Error('无法获取IP地址，服务器响应错误');
                }
                
                const data = await response.json();
                
                // 验证返回的数据格式
                if (data.code === 0 && 
                    typeof data.data === 'object' && 
                    typeof data.data.myip === 'string' && 
                    isValidIp(data.data.myip)) {
                    
                    // 填充IP地址到输入框
                    ipAddressInput.value = data.data.myip;
                    
                    // 显示地理位置信息
                    if (typeof data.data.location === 'string') {
                        locationText.textContent = data.data.location;
                        ipLocation.classList.remove('hidden');
                    }
                    
                    // 自动转换为二进制
                    const binaryResult = ipToBinary(data.data.myip);
                    document.getElementById('binaryInput').value = binaryResult;
                    updateBinaryDisplay(binaryResult);
                    
                    // 更新IP结果显示
                    document.getElementById('ipResult').textContent = data.data.myip;
                    
                    // 更新可视化示例
                    updateVisualizationExample();
                } else {
                    throw new Error('获取的IP地址格式不正确');
                }
            } catch (error) {
                console.error('获取IP地址失败:', error);
                // 可以在这里显示错误消息给用户
            } finally {
                // 隐藏加载状态
                ipLoader.classList.add('hidden');
            }
        }

        // 生成随机IP地址
        function generateRandomIp() {
            // 生成四个0-255之间的随机数
            const octets = [];
            for (let i = 0; i < 4; i++) {
                octets.push(Math.floor(Math.random() * 256));
            }
            
            // 转换为IP地址格式
            return octets.join('.');
        }

        // 初始化二进制显示区域
        function initializeBinaryDisplay() {
            const binaryDisplay = document.getElementById('binaryDisplay');
            binaryDisplay.innerHTML = '';
            
            // 创建4个八位组
            for (let i = 0; i < 4; i++) {
                const octetDiv = document.createElement('div');
                octetDiv.className = 'octet-container';
                
                // 创建字节标题
                const byteTitle = document.createElement('div');
                byteTitle.className = 'text-center font-medium mb-2';
                byteTitle.textContent = `字节 ${i + 1}`;
                octetDiv.appendChild(byteTitle);
                
                // 创建位权行
                const weightRow = document.createElement('div');
                weightRow.className = 'flex gap-1';
                
                // 创建8个位权
                for (let j = 0; j < 8; j++) {
                    const weightDiv = document.createElement('div');
                    weightDiv.className = 'bit-weight w-10 text-center';
                    weightDiv.textContent = Math.pow(2, 7 - j);
                    weightRow.appendChild(weightDiv);
                }
                
                octetDiv.appendChild(weightRow);
                
                // 创建8个位
                const bitRow = document.createElement('div');
                bitRow.className = 'flex gap-1';
                
                for (let j = 0; j < 8; j++) {
                    const bitDiv = document.createElement('div');
                    bitDiv.className = 'bit-box';
                    bitDiv.textContent = '0';
                    bitDiv.dataset.position = i * 8 + j;
                    
                    // 添加点击切换功能
                    bitDiv.addEventListener('click', function() {
                        this.textContent = this.textContent === '0' ? '1' : '0';
                        this.classList.toggle('bit-box-active');
                        updateBinaryInput();
                        updateByteValues();
                        updateVisualizationExample(); // 更新可视化示例
                    });
                    
                    bitRow.appendChild(bitDiv);
                }
                
                octetDiv.appendChild(bitRow);
                
                // 创建字节值显示
                const byteValueDiv = document.createElement('div');
                byteValueDiv.className = 'mt-2 text-center font-mono';
                byteValueDiv.id = `byteValue${i}`;
                byteValueDiv.textContent = '0';
                octetDiv.appendChild(byteValueDiv);
                
                binaryDisplay.appendChild(octetDiv);
            }
            
            updateVisualizationExample(); // 初始化时更新可视化示例
        }
        
        // 更新二进制输入框内容
        function updateBinaryInput() {
            const bits = Array.from(document.querySelectorAll('.bit-box')).map(bit => bit.textContent);
            let binaryString = '';
            
            for (let i = 0; i < 4; i++) {
                binaryString += bits.slice(i * 8, (i + 1) * 8).join('');
                if (i < 3) binaryString += '.';
            }
            
            document.getElementById('binaryInput').value = binaryString;
        }
        
        // 验证IPv4地址格式
        function isValidIp(ip) {
            const regex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
            return regex.test(ip);
        }
        
        // 验证二进制格式
        function isValidBinary(binary) {
            const regex = /^([01]{8}\.){3}[01]{8}$/;
            return regex.test(binary);
        }
        
        // IP转二进制
        function ipToBinary(ip) {
            const parts = ip.split('.');
            return parts.map(part => {
                const binary = parseInt(part, 10).toString(2);
                return binary.padStart(8, '0');
            }).join('.');
        }
        
        // 二进制转IP
        function binaryToIp(binary) {
            const parts = binary.split('.');
            return parts.map(part => parseInt(part, 2)).join('.');
        }
        
        // 更新二进制显示
        function updateBinaryDisplay(binary) {
            const bits = binary.replace(/\./g, '').split('');
            const bitBoxes = document.querySelectorAll('.bit-box');
            
            bitBoxes.forEach((box, index) => {
                box.textContent = bits[index];
                if (bits[index] === '1') {
                    box.classList.add('bit-box-active');
                } else {
                    box.classList.remove('bit-box-active');
                }
            });
            
            updateByteValues();
            updateVisualizationExample(); // 更新可视化示例
        }
        
        // 更新字节值显示
        function updateByteValues() {
            for (let i = 0; i < 4; i++) {
                const bits = Array.from(document.querySelectorAll('.bit-box'))
                    .slice(i * 8, (i + 1) * 8)
                    .map(bit => bit.textContent);
                
                const byteValue = parseInt(bits.join(''), 2);
                document.getElementById(`byteValue${i}`).textContent = byteValue;
            }
        }
        
        // 更新可视化示例
        function updateVisualizationExample() {
            const visualizationContainer = document.getElementById('visualizationExample');
            const bits = Array.from(document.querySelectorAll('.bit-box')).map(bit => bit.textContent);
            
            // 如果所有位都是0，显示默认信息
            if (bits.every(bit => bit === '0')) {
                visualizationContainer.innerHTML = `
                    <p class="text-center text-gray-500 italic">输入IP地址并转换为二进制以查看动态可视化</p>
                `;
                return;
            }
            
            // 生成四个字节的可视化
            let visualizationHtml = '';
            for (let i = 0; i < 4; i++) {
                const byteBits = bits.slice(i * 8, (i + 1) * 8);
                const byteValue = parseInt(byteBits.join(''), 2);
                
                visualizationHtml += `
                    <div class="flex flex-wrap gap-2 mb-3">
                        ${byteBits.map(bit => `
                            <div class="w-6 h-6 ${bit === '1' ? 'bg-primary/30' : 'bg-gray-300'} rounded-full"></div>
                        `).join('')}
                        <span class="text-gray-700 font-mono">= ${byteValue}</span>
                    </div>
                `;
            }
            
            // 计算当前IP地址（不依赖DOM元素）
            const ipParts = [];
            for (let i = 0; i < 4; i++) {
                const byteBits = bits.slice(i * 8, (i + 1) * 8);
                ipParts.push(parseInt(byteBits.join(''), 2));
            }
            const currentIp = ipParts.join('.');
            
            visualizationHtml += `
                <p class="text-sm text-gray-600 mt-2">
                    上面的图示展示了IP地址 <span class="font-mono">${currentIp}</span> 的二进制表示。蓝色圆圈表示"1"，灰色圆圈表示"0"。
                </p>
            `;
            
            visualizationContainer.innerHTML = visualizationHtml;
        }
        
        // 事件监听
        document.addEventListener('DOMContentLoaded', function() {
            initializeBinaryDisplay();
            
            // 获取用户IP地址
            fetchUserIp();
            
            // 随机IP按钮
            document.getElementById('randomIpBtn').addEventListener('click', function() {
                const randomIp = generateRandomIp();
                document.getElementById('ipAddress').value = randomIp;
                
                // 隐藏错误消息和位置信息
                document.getElementById('ipError').classList.add('hidden');
                document.getElementById('ipLocation').classList.add('hidden');
                
                // 自动转换为二进制
                const binaryResult = ipToBinary(randomIp);
                document.getElementById('binaryInput').value = binaryResult;
                updateBinaryDisplay(binaryResult);
                
                // 更新IP结果显示
                document.getElementById('ipResult').textContent = randomIp;
                
                // 添加按钮动画效果
                this.classList.add('animate-pulse');
                setTimeout(() => {
                    this.classList.remove('animate-pulse');
                }, 500);
            });
            
            // IP转二进制按钮
            document.getElementById('convertToBinaryBtn').addEventListener('click', function() {
                const ipInput = document.getElementById('ipAddress').value.trim();
                const ipError = document.getElementById('ipError');
                
                if (!isValidIp(ipInput)) {
                    ipError.classList.remove('hidden');
                    return;
                }
                
                ipError.classList.add('hidden');
                const binaryResult = ipToBinary(ipInput);
                document.getElementById('binaryInput').value = binaryResult;
                updateBinaryDisplay(binaryResult);
                
                // 添加动画效果
                const binaryDisplay = document.getElementById('binaryDisplay');
                binaryDisplay.classList.add('animate-pulse');
                setTimeout(() => {
                    binaryDisplay.classList.remove('animate-pulse');
                }, 1000);
            });
            
            // 二进制转IP按钮
            document.getElementById('convertToIpBtn').addEventListener('click', function() {
                const binaryInput = document.getElementById('binaryInput').value.trim();
                const binaryError = document.getElementById('binaryError');
                
                if (!isValidBinary(binaryInput)) {
                    binaryError.classList.remove('hidden');
                    return;
                }
                
                binaryError.classList.add('hidden');
                const ipResult = binaryToIp(binaryInput);
                document.getElementById('ipResult').textContent = ipResult;
                
                // 添加动画效果
                const ipResultEl = document.getElementById('ipResult');
                ipResultEl.classList.add('animate-pulse');
                setTimeout(() => {
                    ipResultEl.classList.remove('animate-pulse');
                }, 1000);
                
                updateVisualizationExample(); // 更新可视化示例
            });
            
            // 练习1检查答案
            document.getElementById('checkExercise1').addEventListener('click', function() {
                const answer = document.getElementById('exercise1').value.trim();
                const resultEl = document.getElementById('exercise1Result');
                
                if (answer === '00001010.00000000.00000000.00000001') {
                    resultEl.textContent = '✅ 正确！10.0.0.1 的二进制表示是 00001010.00000000.00000000.00000001';
                    resultEl.className = 'mt-2 text-sm text-green-600';
                } else {
                    resultEl.textContent = '❌ 不正确。正确答案是 00001010.00000000.00000000.00000001';
                    resultEl.className = 'mt-2 text-sm text-red-500';
                }
                
                resultEl.classList.remove('hidden');
            });
            
            // 练习2检查答案
            document.getElementById('checkExercise2').addEventListener('click', function() {
                const answer = document.getElementById('exercise2').value.trim();
                const resultEl = document.getElementById('exercise2Result');
                
                if (answer === '224.16.2.3') {
                    resultEl.textContent = '✅ 正确！11100000.00010000.00000010.00000011 的IPv4格式是 224.16.2.3';
                    resultEl.className = 'mt-2 text-sm text-green-600';
                } else {
                    resultEl.textContent = '❌ 不正确。正确答案是 224.16.2.3';
                    resultEl.className = 'mt-2 text-sm text-red-500';
                }
                
                resultEl.classList.remove('hidden');
            });
            
            // 输入框事件处理
            document.getElementById('ipAddress').addEventListener('input', function() {
                document.getElementById('ipError').classList.add('hidden');
            });
            
            document.getElementById('binaryInput').addEventListener('input', function() {
                document.getElementById('binaryError').classList.add('hidden');
            });
            
            // 自动格式化二进制输入
            document.getElementById('binaryInput').addEventListener('input', function(e) {
                let value = e.target.value.replace(/[^01]/g, '');
                let formattedValue = '';
                
                for (let i = 0; i < value.length; i++) {
                    formattedValue += value[i];
                    if ((i + 1) % 8 === 0 && (i + 1) !== value.length) {
                        formattedValue += '.';
                    }
                }
                
                // 防止光标跳到末尾
                const start = e.target.selectionStart;
                const end = e.target.selectionEnd;
                
                e.target.value = formattedValue;
                
                // 调整光标位置
                let newPos = start;
                if (start > 0 && (start % 9 === 0)) {
                    newPos++;
                }
                e.target.setSelectionRange(newPos, newPos);
                
                // 如果输入完整的32位二进制，自动更新显示
                if (formattedValue.length === 35) {
                    updateBinaryDisplay(formattedValue);
                }
            });
        });
    </script>
</body>
</html>